package com.sjh.lib_app.baseui

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.template.IProvider
import com.alibaba.android.arouter.launcher.ARouter
import com.sjh.lib_app.NoLazyFragment
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.lang.ref.WeakReference

/**
 * 基础Fragment
 *
 * 0. 使用 ARouter 的 Autowired 注解时，已自动添加 ARouter.getInstance().inject(this) 这行代码
 * 1. 使用 EventBus 时，不需要注册与取消注册，baseActivity里面自动判断了，如果有使用EventBus,会自动注册与取消
 * 2. 默认使用了懒加载，可以使用 NoLazyFragment 注解来解除懒加载。
 *    注：懒加载的实现方式已兼容 老版 和 setMaxLifecycle 方法实现的懒加载，但是对于新版的懒加载实现方式，
 *        没有做大量的测试，如果出现问题请及时联系 rd_liguo@yuzhua.com
 * @author Extends
 * @date 2020/6/10
 */
abstract class BaseFragment:Fragment(), IProvider {

    /**
     * 是否使用了EvnetBus
     */
    private var hasEvent = false

    /**
     * 判断数据是否刷新过了
     */
    private var isInit = false

    /**
     * 判断控件是否创建了
     */
    private var isViewInit = false

    //临时测试使用
    private var isLog = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//        isLog = this::class.java.simpleName == "MessageFragment"
        tempSavedInstanceState = WeakReference(savedInstanceState)
        return initContentView(inflater,container,savedInstanceState)
    }

    /**
     * 初始化内容View
     */
    private fun initContentView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?):View {
        val view = onCreatRootView(inflater,container,savedInstanceState)
        return when(view){
            is Int -> inflater.inflate(view,container,false)
            is View -> view
            else -> throw NullPointerException(this::class.java.simpleName + "'s contentView is null")
        }
    }

    private fun initFragment(){
        // 判断是否使用了EvnetBus
        initEvent()
        // 判断是否使用了ARouter的Autowired注解
        initARouter()
        onInitView(tempSavedInstanceState?.get())

        if(hasEvent){
            EventBus.getDefault().register(this)
        }
    }

    private var tempSavedInstanceState:WeakReference<Bundle?>? = null

    override fun onResume() {
        super.onResume()
        // 判断是否关闭懒加载，默认是开启的
        if(!isViewInit && !isInit){
            isViewInit = true
            if(this::class.java.isAnnotationPresent(NoLazyFragment::class.java)){
                initFragment()
            }else{
//                if(isLog){
//                    "11111111".loge()
//                }
                //界面已初始化成功，判断界面是否可见
                if(!isHidden){
//                    if(isLog){
//                        "22222222".loge()
//                    }
                    lazyInitData()
                }
            }
        }

    }

//    override fun onActivityCreated(savedInstanceState: Bundle?) {
//        tempSavedInstanceState = WeakReference(savedInstanceState)
//        super.onActivityCreated(savedInstanceState)
//        // 判断是否关闭懒加载，默认是开启的
//        if(this::class.java.isAnnotationPresent(NoLazyFragment::class.java)){
//            initFragment()
//        }else{
//            if(isLog){
//                "11111111".loge()
//            }
//            //界面已初始化成功，判断界面是否可见
//            isViewInit = true
//            if(!isHidden){
//                if(isLog){
//                    "22222222".loge()
//                }
//                lazyInitData()
//            }
//        }
//    }

    /**
     * 在普通的activity中判断是否隐藏
     */
    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
//        if(isLog){
//            "33333333333".loge()
//        }
        if(hidden) onUserHint() else {lazyInitData();onUserVisible()}

    }

    /**
     * 对用户是否可见
     * 注意：这个方法仅仅工作在FragmentPagerAdapter中，不能被使用在一个普通的activity中
     */
    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
//        if(isLog){
//            "444444444444".loge()
//        }
        lazyInitData()
        if(isVisibleToUser) {
            onUserVisible()
        }else
            onUserHint()
    }

    /**
     * 用户看见时触发
     */
    open fun onUserVisible(){ }

    /**
     * 用户看不见时触发
     */
    open fun onUserHint(){ }

    /**
     * 懒加载数据
     */
    private fun lazyInitData(){
        //判断界面是否已经初始化，数据是否是第一次加载，判断用户是否可见
        if(isViewInit && !isInit && userVisibleHint){
//            if(isLog){
//                "555555555555".loge()
//            }
            isInit = true
            initFragment()
        }
    }

    /**
     * @return ResLayout | View
     */
    protected abstract fun onCreatRootView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?):Any
    protected abstract fun onInitView(savedInstanceState: Bundle?)

    /**
     * IProvider 需要重写的方法
     */
    override fun init(context: Context?) {

    }

    override fun onDestroyView() {
        super.onDestroyView()
        if (hasEvent&& EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().unregister(this)
        }
    }

    /**
     * 判断是否使用了EventBus
     */
    private fun initEvent(){
        hasEvent = hasAnnotationFromMethods(Subscribe::class.java)
    }

    /**
     * 判断方法中是否有指定的注解
     */
    private fun hasAnnotationFromMethods(clazz: Class<out Annotation>):Boolean{
        this::class.java.methods.forEach {
            if(it.isAnnotationPresent(clazz)){
                return true
            }
        }
        return false
    }

    /**
     * 判断是否使用了ARouter的Autowired注解
     */
    private fun initARouter(){
        try {
            Class.forName("${javaClass.name}\$\$ARouter\$\$Autowired")
            ARouter.getInstance().inject(this)
        }catch (e:Exception){}
    }
}